package com.easypan.controller;


import com.easypan.annotation.GlobalInterceptor;
import com.easypan.annotation.VerifyParam;
import com.easypan.entity.config.AppConfig;
import com.easypan.entity.contants.Constants;
import com.easypan.entity.dto.CreateImageCode;
import com.easypan.entity.dto.SessionWebUserDto;
import com.easypan.entity.enums.VerifyRegexEnum;
import com.easypan.entity.po.UserInfo;
import com.easypan.entity.vo.ResponseVO;
import com.easypan.exception.BusinessException;
import com.easypan.service.EmailCodeService;
import com.easypan.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.CropImageFilter;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * <p>
 * 用户信息 前端控制器
 * </p>
 *
 * @author Yandel
 * @since 2025-06-04
 */
@Api(tags = "登录注册相关接口")
@RestController("accountController")
public class UserInfoController extends ABaseController {
    //日志
    private static final Logger logger = LoggerFactory.getLogger(UserInfoController.class);


    private static final String CONTENT_TYPE = "Content-Type";
    private static final String CONTENT_TYPE_VALUE = "application/json;charset=UTF-8";

    @Resource
    private EmailCodeService emailCodeService;

    @Resource
    private UserInfoService userInfoService;


    @Resource
    private AppConfig appConfig;

    /**
     * 生成验证码
     *
     * @param response
     * @param session
     * @param type
     * @throws IOException
     */
    @ApiOperation("生成验证码")
    @GetMapping("/checkCode")
    public void checkCode(HttpServletResponse response, HttpSession session, Integer type) throws IOException {
        //创建验证码
        CreateImageCode imageCode = new CreateImageCode(130, 38, 5, 10);
        //设置图片验证码——防止浏览器缓存图片
        response.setHeader("Pragma", "no-cache");//设置响应头防止缓存
        response.setHeader("Cache-Control", "no-cache");//确保浏览器不会缓存验证码图片，保证每次请求都是新的验证码。
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        String code = imageCode.getCode();// 获取生成的验证码字符串
        if (type == null || type == 0) {
            //表示普通登录/注册验证码，保存为 CHECK_CODE_KEY
            session.setAttribute(Constants.CHECK_CODE_KEY, code);
        } else {
            //表示邮箱验证码，保存为 CHECK_CODE_KEY_EMAIL
            session.setAttribute(Constants.CHECK_CODE_KEY_EMAIL, code);
        }
        //将图片数据直接输出给前端，显示在页面上
        imageCode.write(response.getOutputStream());
    }

    /**
     * 发送邮件验证码
     *
     * @param session
     * @param email
     * @param checkCode
     * @param type
     * @return
     */
    @ApiOperation("发送邮件验证码")
    @PostMapping("/sendEmailCode")
    public ResponseVO sendEmailCode(HttpSession session,
                                    //自定义注解校验参数     正则校验、最大长度、最小长度
                                    @VerifyParam(required = true, regex = VerifyRegexEnum.EMAIL, max = 50) String email,
                                    @VerifyParam(required = true) String checkCode,
                                    @VerifyParam(required = true) Integer type) {
        try {
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY_EMAIL))) {
                throw new RuntimeException("图片验证码不正确");
            }
            emailCodeService.sendEmailCode(email, type);

            //返回VO
            return getSuccessResponseVO(null);
        } finally {
            //一定执行  销毁邮箱
            session.removeAttribute(Constants.CHECK_CODE_KEY_EMAIL);
        }
    }


    @ApiOperation("注册")
    @PostMapping("/register")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public ResponseVO register(HttpSession session,
                               @VerifyParam(required = true, regex = VerifyRegexEnum.EMAIL, max = 50) String email,
                               @VerifyParam(required = true, max = 20) String nickName,
                               @VerifyParam(required = true, regex = VerifyRegexEnum.PASSWORD, min = 8, max = 18) String password,
                               @VerifyParam(required = true) String checkCode,
                               @VerifyParam(required = true) String emailCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) {
                throw new BusinessException("图片验证码不正确");
            }
            userInfoService.register(email, nickName, password, emailCode);
            return getSuccessResponseVO(null);
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY);
        }

    }



    @ApiOperation("登录")
    @PostMapping("/login")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public ResponseVO login(HttpSession session, HttpServletRequest request,
                            @VerifyParam(required = true) String email,
                            @VerifyParam(required = true) String password,
                            @VerifyParam(required = true) String checkCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) {
                throw new BusinessException("图片验证码不正确");
            }
            SessionWebUserDto sessionWebUserDto = userInfoService.login(email, password);
            session.setAttribute(Constants.SESSION_KEY, sessionWebUserDto);
            return getSuccessResponseVO(sessionWebUserDto);
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY);
        }
    }


    @ApiOperation("重置密码")
    @PostMapping("/resetPwd")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public ResponseVO resetPwd(HttpSession session,
                               @VerifyParam(required = true, regex = VerifyRegexEnum.EMAIL, max = 150) String email,
                               @VerifyParam(required = true, regex = VerifyRegexEnum.PASSWORD, min = 8, max = 18) String password,
                               @VerifyParam(required = true) String checkCode,
                               @VerifyParam(required = true) String emailCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) {
                throw new BusinessException("图片验证码不正确");
            }
            userInfoService.resetPwd(email, password, emailCode);
            return getSuccessResponseVO(null);
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY);
        }
    }


    @ApiOperation("获取用户头像")
    @GetMapping("/getAvatar/{userId}")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public void getAvatar(HttpServletResponse response,
                          @VerifyParam(required = true)
                          @PathVariable("userId") String userId) {
        String avatarFolderName = Constants.FILE_FOLDER_FILE + Constants.FILE_FOLDER_AVATAR_NAME;//        /file/avatar/
        File folder = new File(appConfig.getProjectFolder() + avatarFolderName);//   E:/webser/web_app/easypan/ + avatarFollderName
        if (!folder.exists()) { //E:/webser/web_app/easypan   /file/avatar
            folder.mkdirs();
        }
        String avatarPath = appConfig.getProjectFolder() + avatarFolderName + userId + Constants.AVATAR_SUFFIX;
        File file = new File(avatarPath);
        if (!file.exists()){
            if (!new File(appConfig.getProjectFolder() + avatarFolderName + Constants.AVATAR_DEFUALT).exists()) {
                printNoDefaultImage(response);
                return;
            }
            avatarPath = appConfig.getProjectFolder() + avatarFolderName + Constants.AVATAR_DEFUALT;
        }
        response.setContentType("image/jpg");
        //读取文件
        readFile(response, avatarPath);
    }

    private void printNoDefaultImage(HttpServletResponse response) {
        response.setHeader(CONTENT_TYPE, CONTENT_TYPE_VALUE);
        response.setStatus(HttpStatus.OK.value());
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.print("请在头像目录下放置默认头像default_avatar.jpg");
            writer.close();
        } catch (Exception e) {
            logger.error("输出无默认图失败", e);
        } finally {
            writer.close();
        }
    }

    //TODO 获取用户空间



    @ApiOperation("退出登录")
    @PostMapping("/logout")
    public ResponseVO logout(HttpSession session) {
        session.invalidate();
        return getSuccessResponseVO(null);
    }

    @ApiOperation("更新用户头像")
    @PostMapping("/updateUserAvatar")
    @GlobalInterceptor
    /**
     * 更新用户头像
     * @param session 当前用户的会话对象，用于获取登录用户信息
     * @param avatar MultipartFile表示上传的文件数据，包含文件内容、原始文件名等元数据。
     *               Spring MVC自动将HTTP请求中的文件部分封装成MultipartFile对象。
     * @return ResponseVO 返回操作结果，成功或失败信息
     */
    public ResponseVO updateUserAvatar(HttpSession session, MultipartFile avatar) {
        // 获取当前登录用户信息
        SessionWebUserDto webUserDto = getUserInfoFromSession(session);
        if (webUserDto == null) {
            throw new BusinessException("用户未登录");
        }
        // 定义头像存储路径
        String baseFolder = appConfig.getProjectFolder() + Constants.FILE_FOLDER_FILE;
        File targetFileFolder = new File(baseFolder + Constants.FILE_FOLDER_AVATAR_NAME);
        if (!targetFileFolder.exists()) {
            targetFileFolder.mkdirs();
        }
        File targetFile = new File(targetFileFolder.getPath() + "/" + webUserDto.getUserId() + Constants.AVATAR_SUFFIX);

        try {
            // 将上传的文件写入目标路径
            avatar.transferTo(targetFile);

        } catch (IOException e) {
            logger.error("头像上传失败", e);
            throw new BusinessException("头像上传失败，请重试");
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setQqAvatar("");
        userInfoService.updateUserInfoByUser(userInfo,  webUserDto.getUserId());
        webUserDto.setAvatar(null);
        session.setAttribute(Constants.SESSION_KEY, webUserDto);

        // 返回成功响应
        return getSuccessResponseVO(null);
    }


    //TODO 修改密码


    //TODO QQ登录


    //TODO  QQ登录回调

}
